package com.boot.service.impl;

import com.boot.mq.MqProducer;
import com.boot.exception.BusinessException;
import com.boot.mapper.AccountMapper;
import com.boot.pojo.Account;
import com.boot.pojo.CompensateRecords;
import com.boot.service.CompensateRecordsService;
import com.boot.service.PaymentService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
public class PaymentServiceImpl implements PaymentService {
    private final RedisTemplate redisTemplate;
    private final AccountMapper accountMapper;
    private final CompensateRecordsService compensateRecordsService;



    @Override
    @Transactional(rollbackFor = BusinessException.class)
    public boolean deduct(Long userId, BigDecimal amount) {
        //查询余额是否足够，使用redis减轻DB压力
        String cacheKey = "account:balance:" + userId;
        BigDecimal cachedBalance = (BigDecimal) redisTemplate.opsForValue().get(cacheKey);
        if (cachedBalance == null) {
            BigDecimal dbBalance = accountMapper.getBalanceByUserId(userId);
            if (dbBalance == null) {
                throw new BusinessException("账户不存在", 10000);
            }
            redisTemplate.opsForValue().set(cacheKey, dbBalance, 1, TimeUnit.DAYS);
            cachedBalance = dbBalance;
            System.out.println("余额为：" +dbBalance);
            System.out.println(redisTemplate.opsForValue().get(cacheKey));
        }
        if (cachedBalance.compareTo(amount) < 0) {
            throw new BusinessException("余额不足", 10001);
        }
        //执行扣款
        int updated = accountMapper.deductBalance(userId, amount);
        if (updated == 0) {
            //扣款失败，可能余额不足等
            throw new BusinessException("扣款失败，余额不足", 10002);
        }
        //更新缓存
        redisTemplate.opsForValue().set(cacheKey, cachedBalance.multiply(amount), 1, TimeUnit.DAYS);

        compensateRecordsService.recordCompensation(userId, amount, "deduct");
        return true;
    }

    @Override
    @Transactional(rollbackFor = BusinessException.class)
    public boolean compensateDeduct(CompensateRecords compensateRecords) {
        //补偿金额操作
        CompensateRecords record = compensateRecordsService.getCompensateRecordsForUpdate(compensateRecords.getId());
        if (record == null) {
            throw new BusinessException("无补偿记录存在", 10005);
        }
        //查询用户记录，确保没有在补偿中
        Account userAccount = accountMapper.selectByUserIdForUpdate(compensateRecords.getUserId());
        System.out.println(userAccount);
        if (userAccount.getCompensating()) {
            throw new BusinessException("账户正在进行补偿，请稍后", 10006);
        }
        try {
            //修改并加锁，防止并发
            accountMapper.markAndCompensate(compensateRecords.getUserId(), compensateRecords.getAmount());
            //记录更新为完成
            record.setStatus(1);
            System.out.println(record);
            compensateRecordsService.updateCompensateRecords(record);
            return true;
        } catch (Exception e) {
            throw new BusinessException("补偿异常：" + e.getMessage(), 10008);
        } finally {
            accountMapper.setCompensating(compensateRecords.getUserId(), false);
        }
    }
}
